home *** CD-ROM | disk | FTP | other *** search
- //=============================================================================
- // File: proto_un.h
- // Contents: Declarations for DwClientProtocol
- // Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
- // WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html
- //
- // Copyright (c) 1996, 1997 Douglas W. Sauder
- // All rights reserved.
- //
- // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
- // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
- // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
- // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- //
- // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
- // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
- // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
- // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- //
- //=============================================================================
-
- #ifndef DW_PROTOCOL_H
- #define DW_PROTOCOL_H
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- #ifndef DW_CONFIG_H
- #include <mimelib/config.h>
- #endif
-
- #ifndef DW_STRING_H
- #include <mimelib/string.h>
- #endif
-
-
- class DwObserver {
- public:
- virtual void Notify()=0;
- };
-
-
- //=============================================================================
- //+ Name DwProtocolClient -- Base class for all protocol clients
- //+ Description
- //. {\tt DwProtocolClient} is the base class for other classes that implement
- //. specific protocols, such as SMTP, POP, and NNTP. {\tt DwProtocolClient}
- //. serves two purposes. First, It combines operations common to all its
- //. derived classes, such as opening a TCP connection to the server. Second,
- //. it provides a platform-independent interface to the network services
- //. required by its subclasses.
- //.
- //. There are two separate implementations of {\tt DwProtocolClient}: one for
- //. Berkeley sockets under UNIX, and one for Winsock under Win32. The
- //. interface is the same for both implementations, thus providing platform
- //. independence.
- //.
- //. There are two platform-specific details that you should be aware of.
- //. First, if you are writing a UNIX program, you should be sure to handle
- //. the SIGPIPE signal. This signal is raised when a program tries to write
- //. to a TCP connection that was shutdown by the remote host. The default
- //. action for this signal is to terminate the program. To prevent this
- //. from happening in your program, you should either catch the signal or
- //. tell the operating system to ignore it. Second, if you are writing a
- //. Win32 application for Windows NT or Windows95, you should be aware of
- //. the fact that the constructor calls the Winsock function
- //. {\tt WSAStartup()} to initialize the Winsock DLL. (The destructor
- //. calls {\tt WSACleanup()}.) Because it is possible for {\tt WSAStartup()}
- //. to fail, it is also possible that the constructor may fail. To verify
- //. that the constructor has succeeded, call the member function
- //. {\tt LastError()} and check that it returns zero.
- //.
- //. To open a connection to a server, call {\tt Open()} with the server name
- //. and TCP port number as arguments. {\tt Open()} is declared virtual;
- //. derived classes may override this member function. {\tt Open()} may fail,
- //. so you should check the return value to verify that it succeeded. To close
- //. the connection, call {\tt Close()}. To check if a connection is open,
- //. call {\tt IsOpen()}. {\tt IsOpen()} returns a value that indicates whether
- //. or not a call to {\tt Open()} was successful; it will not detect failure
- //. in the network or a close operation by the remote host.
- //.
- //. {\tt DwProtocolClient} sets a timeout on receive operations on the TCP
- //. connection. The default value of the timeout period is 90 seconds. To
- //. change the default value, call {\tt SetReceiveTimeout()} and pass the
- //. new value as an argument.
- //.
- //. Whenever {\tt DwProtocolClient} cannot complete an operation, it is because
- //. an error has occurred. Most member functions indicate that an error has
- //. occurred via their return values. For most member functions, a return
- //. value of -1 indicates an error. To get the specific error that has
- //. occurred, call {\tt LastError()}, which returns either the system error
- //. code or a MIME++ defined error code. To get a text string that describes
- //. the error, call {\tt LastErrorStr()}.
- //.
- //. Some errors are also considered "failures." A failure occurs when an
- //. operation cannot be completed because of conditions external to the
- //. program. For example, a failure occurs when the network is down or
- //. when an application's user enters bad input. Errors that occur because
- //. of programmer error are not considered failures. If an error occurs,
- //. you should call {\tt LastError()} to determine the error, but you should
- //. also call {\tt LastFailure()} to determine if a failure occurred. In
- //. interactive applications, failures should always be reported to the
- //. application's user. To get a text string that describes a failure,
- //. call {\tt LastFailureStr()}.
- //.
- //. It is possible to translate the error and failure message strings to a
- //. language other than English. To do this, you may override the virtual
- //. function {\tt HandleError()}.
- //=============================================================================
-
- //+ Noentry mFailureCode mFailureStr mErrorCode mErrorStr mLastCommand
- //+ Noentry mIsDllOpen mIsOpen mSocket mPort mServerName mReceiveTimeout
-
-
- class DwProtocolClient {
-
- public:
-
- enum Failure {
- kFailNoFailure = 0, // No failure
- kFailNoWinsock = 1, // A usable Winsock DLL could not be found
- kFailNetDown = 2, // The network is down
- kFailHostNotFound = 3, // The server was not found
- kFailConnReset = 4, // The connection was reset
- kFailNetUnreachable = 5, // The network is unreachable
- kFailTimedOut = 6, // Timed out while waiting for an operation
- // to complete
- kFailConnDropped = 7,
- kFailConnRefused = 8,
- kFailNoResources = 9
- };
- //. Enumerated values for failures.
-
- enum Error {
- kErrNoError = 0,
- kErrUnknownError = 0x4000,
- kErrBadParameter = 0x4001,
- kErrBadUsage = 0x4002,
- kErrNoWinsock = 0x4003, // Win32
- kErrHostNotFound = 0x5000, // UNIX
- kErrTryAgain = 0x5001, // UNIX
- kErrNoRecovery = 0x5002, // UNIX
- kErrNoData = 0x5003, // UNIX
- kErrNoAddress = 0x5004 // UNIX
- };
- //. MIME++-defined error codes.
-
- protected:
-
- DwProtocolClient();
- //. Initializes the {\tt DwProtocolClient} object.
- //. In a Win32 environment, this constructor calls {\tt WSAStartup()}
- //. to initialize the Winsock DLL. To verify that the DLL was initialized
- //. successfully, call the member function {\tt LastError()} and verify
- //. that it returns zero.
-
- public:
-
- virtual ~DwProtocolClient();
- //. Frees the resources used by this object.
- //. In a Win32 environment, the destructor calls {\tt WSACleanup()}.
-
- virtual int Open(const char* aServer, DwUint16 aPort);
- //. Opens a TCP connection to the server {\tt aServer} at port {\tt aPort}.
- //. {\tt aServer} may be either a host name, such as "smtp.acme.com" or an
- //. IP number in dotted decimal format, such as "147.81.64.59". If the
- //. connection attempt succeeds, {\tt Open()} returns 0; othewise, it
- //. returns -1. To determine what error occurred when the connection
- //. attempt fails, call the member function {\tt LastError()}. To
- //. determine if a failure also occurred, call the member function
- //. {\tt LastFailure()}.
-
- DwBool IsOpen() const;
- //. Returns true value if a connection to the server is open.
- //. {\tt IsOpen()} will return a true value if a call to {\tt Open()} was
- //. successful; it will not detect failure in the network or a close
- //. operation by the remote host.
-
- int Close();
- //. Closes the connection to the server. Returns 0 if successful, or
- //. returns -1 if unsuccessful.
-
- int SetReceiveTimeout(int aSecs);
- //. Changes the default timeout for receive operations on the socket to
- //. {\tt aSecs} seconds.
- //. The default value is 90 seconds.
-
- int LastCommand() const;
- //. Returns an enumerated value indicating the last command sent to
- //. the server. Enumerated values are defined in subclasses of
- //. {\tt DwProtocolClient}.
-
- int LastFailure() const;
- //. Returns an enumerated value indicating what failure last occurred.
-
- const char* LastFailureStr() const;
- //. Returns a failure message string associated with the failure code
- //. returned by {\tt LastFailure()}.
-
- int LastError() const;
- //. Returns an error code for the last error that occurred. Normally, the
- //. error code returned is an error code returned by a system call;
- //. {\tt DwProtocolClient} does no translation of error codes returned
- //. by system calls. In some cases, an error code defined by MIME++ may
- //. returned to indicate improper use of the {\tt DwProtocolClient} class.
-
- const char* LastErrorStr() const;
- //. Returns an error message string associated with the error code returned
- //. by {\tt LastError()}.
-
- protected:
-
- enum {
- kWSAStartup=1, // Win32
- kgethostbyname,
- ksocket,
- ksetsockopt,
- kconnect,
- ksend,
- krecv,
- kclose, // UNIX
- kclosesocket, // Win32
- kselect
- };
- // Enumerated values that indicate the system call that detected
- // an error
-
- DwBool mIsDllOpen;
- DwBool mIsOpen;
- int mSocket;
- DwUint16 mPort;
- char* mServerName;
- int mReceiveTimeout;
- int mLastCommand;
- int mFailureCode;
- const char* mFailureStr;
- int mErrorCode;
- const char* mErrorStr;
-
- virtual void HandleError(int aErrorCode, int aSystemCall);
- //. Interprets error codes. {\tt aErrorCode} is an error code,
- //. which may be a system error code, or an error code defined by
- //. {\tt DwProtocolClient}. {\tt aSystemCall} is an enumerated value
- //. defined by {\tt DwProtocolClient} that indicates the last system
- //. call made, which should be the system call that set the error code.
- //. {\tt HandleError()} sets values for {\tt mErrorStr},
- //. {\tt mFailureCode}, and {\tt mFailureStr}.
-
- int PSend(const char* aBuf, int aBufLen);
- //. Sends {\tt aBufLen} characters from the buffer {\tt aBuf}. Returns
- //. the number of characters sent. If the number of characters sent
- //. is less than the number of characters specified in {\tt aBufLen},
- //. the caller should call {\tt LastError()} to determine what, if any,
- //. error occurred. To determine if a failure also occurred, call the
- //. member function {\tt LastFailure()}.
-
- int PReceive(char* aBuf, int aBufSize);
- //. Receives up to {\tt aBufSize} characters into the buffer {\tt aBuf}.
- //. Returns the number of characters received. If zero is returned, the
- //. caller should call the member function {\tt LastError()} to determine
- //. what, if any, error occurred. To determine if a failure also occurred,
- //. call the member function {\tt LastFailure()}.
-
- };
-
- #endif
-